package com.yanqu.road.logic.activity.tongbing.logic;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.logic.activity.tongbing.entiety.TongBingMapRoute;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class TongBingMapLogic {

    /**
     * 地图数据，找客户端要
     */
    public static String MAP_PARAM = "{\"cityLink\":[\"10001_10002\",\"10002_10003\",\"10002_10004\",\"10003_10006\",\"10005_10006\",\"10005_10007\",\"10006_10008\",\"10007_10009\",\"10007_10035\",\"10009_10013\",\"10011_10013\",\"10011_10016\",\"10011_10050\",\"10013_10045\",\"10014_10016\",\"10016_10018\",\"10016_10019\",\"10017_10018\",\"10017_10021\",\"10019_10020\",\"10019_10052\",\"10020_10024\",\"10021_10023\",\"10022_10055\",\"10022_10058\",\"10023_10024\",\"10023_10026\",\"10025_10026\",\"10025_10028\",\"10028_10029\",\"10028_10065\",\"10029_10058\",\"10030_10032\",\"10030_10069\",\"10031_10032\",\"10031_10035\",\"10032_10033\",\"10033_10034\",\"10033_10036\",\"10034_10035\",\"10034_10042\",\"10036_10037\",\"10036_10074\",\"10037_10038\",\"10037_10042\",\"10038_10074\",\"10042_10045\",\"10042_10051\",\"10045_10047\",\"10047_10050\",\"10049_10083\",\"10049_10086\",\"10050_10052\",\"10051_10083\",\"10052_10055\",\"10053_10054\",\"10053_10056\",\"10053_10057\",\"10054_10086\",\"10055_10056\",\"10056_10059\",\"10057_10059\",\"10057_10092\",\"10059_10064\",\"10060_10061\",\"10060_10062\",\"10060_10065\",\"10061_10063\",\"10061_10064\",\"10062_10065\",\"10063_10097\",\"10064_10096\",\"10064_10097\",\"10067_10068\",\"10067_10070\",\"10067_10102\",\"10068_10071\",\"10069_10071\",\"10070_10071\",\"10070_10073\",\"10072_10076\",\"10072_10116\",\"10072_10121\",\"10073_10074\",\"10073_10075\",\"10075_10109\",\"10075_10116\",\"10076_10081\",\"10080_10083\",\"10080_10085\",\"10081_10084\",\"10081_10123\",\"10083_10165\",\"10084_10085\",\"10085_10091\",\"10085_10165\",\"10086_10089\",\"10086_10165\",\"10087_10089\",\"10087_10090\",\"10087_10091\",\"10087_10165\",\"10090_10131\",\"10092_10094\",\"10092_10096\",\"10094_10130\",\"10094_10136\",\"10096_10098\",\"10096_10099\",\"10097_10099\",\"10098_10100\",\"10099_10100\",\"10100_10101\",\"10101_10139\",\"10102_10106\",\"10102_10109\",\"10104_10106\",\"10105_10107\",\"10106_10111\",\"10107_10110\",\"10109_10111\",\"10110_10111\",\"10110_10113\",\"10113_10145\",\"10114_10115\",\"10114_10119\",\"10115_10145\",\"10115_10150\",\"10116_10119\",\"10119_10120\",\"10119_10121\",\"10120_10124\",\"10120_10151\",\"10123_10124\",\"10124_10125\",\"10124_10153\",\"10125_10129\",\"10129_10132\",\"10129_10155\",\"10130_10131\",\"10130_10136\",\"10131_10133\",\"10132_10135\",\"10132_10159\",\"10133_10135\",\"10135_10137\",\"10136_10139\",\"10137_10140\",\"10137_10159\",\"10139_10140\",\"10140_10144\",\"10144_10164\",\"10145_10146\",\"10146_10147\",\"10146_10149\",\"10147_10148\",\"10149_10150\",\"10149_10151\",\"10151_10152\",\"10152_10153\",\"10152_10154\",\"10154_10158\",\"10155_10156\",\"10156_10157\",\"10157_10158\",\"10157_10160\",\"10159_10162\",\"10160_10161\",\"10160_10162\",\"10161_10163\",\"10162_10164\",\"10163_10164\"],\"event\":[10,10,10]}";

    // =============================

    /**
     * 生成地图
     *
     * @return 地点，相邻地点List
     */
    public static Map<Integer, List<Integer>> getCityConnectMapConfig() {
        String mapParam = MAP_PARAM;
        Map<Integer, List<Integer>> listMap = new ConcurrentHashMap<>();

        JSONObject jsonObject = JSONObject.parseObject(mapParam);
        JSONArray cityLink = jsonObject.getJSONArray("cityLink");
        for (Object o : cityLink) {
            String s = String.valueOf(o);
            List<Integer> list = StringUtils.stringToIntegerList(s, "_");
            int cityA = list.get(0);
            int cityB = list.get(1);

            listMap.putIfAbsent(cityA, new ArrayList<>());
            listMap.get(cityA).add(cityB);

            listMap.putIfAbsent(cityB, new ArrayList<>());
            listMap.get(cityB).add(cityA);
        }

        return listMap;
    }

    /**
     * 生成NPC事件位置
     */
    public static int getNpcEventPosNumConfig() {
        String mapParam = MAP_PARAM;
        JSONObject jsonObject = JSONObject.parseObject(mapParam);
        JSONArray event = jsonObject.getJSONArray("event");
        return (int) event.get(0);
    }

    // =============================

    /**
     * 自动寻路
     *
     * @param canMoveRouteMap     过滤了无法移动的点的地图
     * @param battlefieldRouteMap 处于战斗状态的点的地图
     * @param from                出发城市
     * @param to                  到达城市
     * @return 路径，含起点终点，null表示无通路
     */
    public static List<Integer> getRouteList(Map<Integer, List<Integer>> canMoveRouteMap, Map<Integer, List<Integer>> battlefieldRouteMap, int from, int to) {
        // 优先寻路没交战的路线
        List<Integer> routeList = getRouteList(canMoveRouteMap, from, to);
        if (routeList == null || routeList.size() <= 1) {
            // 没交战的路线寻不到则加入有战斗的城池路线
            canMoveRouteMap.putAll(battlefieldRouteMap);
            routeList = getRouteList(canMoveRouteMap, from, to);
        }
        return routeList;
    }

    /**
     * 自动寻路
     *
     * @param canMoveRouteMap 过滤了无法移动的点的地图
     * @param from            出发城市
     * @param to              到达城市
     * @return 路径，含起点终点，null表示无通路
     */
    public static List<Integer> getRouteList(Map<Integer, List<Integer>> canMoveRouteMap, int from, int to) {
        Map<Integer, TongBingMapRoute> movedMap = new HashMap<>();
        Queue<Integer> queue = new LinkedList<>();

        // 添加起点
        movedMap.put(from, new TongBingMapRoute(from, new ArrayList<>()));
        queue.offer(from);

        while (!queue.isEmpty()) {

            // 取当前点和新的路径
            Integer pos = queue.poll();
            TongBingMapRoute lastRoute = movedMap.get(pos);
            List<Integer> curRoute = new ArrayList<>(lastRoute.getRoute());
            curRoute.add(pos);

            // 遍历连接点
            List<Integer> nextPosList = canMoveRouteMap.get(pos);
            if (nextPosList == null || nextPosList.isEmpty()) {
                continue;
            }
            for (Integer nextPos : nextPosList) {

                // 找到终点
                if (nextPos == to) {
                    List<Integer> result = new ArrayList<>(curRoute);
                    result.add(to);
                    return result;
                }

                // 加队列等会儿继续找
                if (!movedMap.containsKey(nextPos)) {
                    queue.offer(nextPos);
                    movedMap.put(nextPos, new TongBingMapRoute(nextPos, curRoute));
                }
            }

        }

        // 没找到
        return null;
    }

    /**
     * 获取阵营中间城市地点
     */
    public static List<Integer> getMiddleCityId(Map<Integer, List<Integer>> cityConnectMap, Set<Integer> camp1PosSet, Set<Integer> camp2PosSet) {
        Set<Integer> lastPosSet = new HashSet<>(); // 走过的点
        List<List<Integer>> lastResultList = new ArrayList<>(); // 多条路线

        Set<Integer> curPosSet = new HashSet<>();
        List<List<Integer>> curResultList = new ArrayList<>(); // 多条路线

        // 准备数据
        lastPosSet.addAll(camp1PosSet);
        for (Integer pos : camp1PosSet) {
            lastResultList.add(Collections.singletonList(pos));
        }

        // 处理
        for (int i = 0; i < 99999; i++) {

            // 找每条可以走的路走一格
            for (List<Integer> route : lastResultList) {
                List<Integer> linked = cityConnectMap.get(route.get(route.size() - 1));
                for (Integer linkedPos : linked) {
                    if (lastPosSet.contains(linkedPos)) {
                        continue;
                    }
                    if (camp1PosSet.contains(linkedPos)) {
                        continue;
                    }
                    ArrayList<Integer> newRoute = new ArrayList<>(route);
                    newRoute.add(linkedPos);
                    curResultList.add(newRoute);
                    curPosSet.add(linkedPos);
                }
            }

            // 无路可走
            if (curResultList.isEmpty()) {
                break;
            }

            // 看看有没有结果
            List<List<Integer>> finalResult = new ArrayList<>();
            for (List<Integer> route : curResultList) {
                if (camp2PosSet.contains(route.get(route.size() - 1))) {
                    finalResult.add(route);
                }
            }

            // 有结果返回
            if (!finalResult.isEmpty()) {

                List<Integer> list = new ArrayList<>();

                // 多个结果都要返回
                for (List<Integer> tmpList : finalResult) {

                    int posIndex = tmpList.size() / 2;
                    list.add(tmpList.get(posIndex)); // 中点

                    if (tmpList.size() % 2 == 0) { // 有两个中点
                        posIndex = posIndex - 1;
                        list.add(tmpList.get(posIndex));
                    }
                }

                return list;
            }

            // 没结果继续找
            lastPosSet = curPosSet;
            lastResultList = curResultList;
            curResultList = new ArrayList<>();
            curPosSet = lastPosSet;
        }

        // 容错返回
        System.err.println("出bug了啊啊啊啊啊啊啊getMiddleCityId");
        return new ArrayList<>(new Random().nextDouble() > 0.5 ? camp1PosSet : camp2PosSet);
    }

}
